package siemenss7smart

import (
	"fmt"
	"net"
	"strings"
	"sync"
)

// Device 设备信息
type Device struct {
	PLCName    string
	PLCtype    int
	IPAddress  string
	CPUSlotNo  string
	LocalTASP  string
	RemoteTASP string
	PLCLinkInfo
	TagGroup map[string]TagGroup
}

// PLCLinkInfo 设备连接状态缓存
type PLCLinkInfo struct {
	StopFlag  bool
	TCPPort   int
	PLCStatue int
	IdelTime  int
}

// type E_PLC_MMType int8

// const (
// 	MM_UNKNOW E_PLC_MMType = 0
// 	MM_I_E    E_PLC_MMType = 1
// 	MM_A_Q    E_PLC_MMType = 2
// 	MM_M_F    E_PLC_MMType = 3
// 	MM_PI_PE  E_PLC_MMType = 4
// 	MM_PQ_PA  E_PLC_MMType = 5
// 	MM_DB     E_PLC_MMType = 6
// 	MM_V      E_PLC_MMType = 7
// 	MM_AI_AE  E_PLC_MMType = 8
// 	MM_AQ_AA  E_PLC_MMType = 9
// )

// func (e E_PLC_MMType) String() string {
// 	switch e {
// 	default:
// 		return ""
// 	}
// }

var wg sync.WaitGroup

var readChan chan []byte
var writeChan chan []byte

// Connect 设备连接的异步方法
func (d Device) Connect() (bool, error) {

	readChan = make(chan []byte, 16)
	writeChan = make(chan []byte, 16)
	go d.connectThread()
	return true, nil
}

func (d Device) connectThread() bool {

	d.PLCStatue = 1 //正在连接状态
	tcpAddr, _ := net.ResolveTCPAddr("tcp", d.IPAddress)
	conn, err := net.DialTCP("tcp", nil, tcpAddr)

	if err != nil {
		fmt.Printf("Connect to %v failed! error:%v", tcpAddr, err.Error())
		return false
	}

	defer conn.Close()
	fmt.Printf("%v : Connected", conn.LocalAddr().String())
	wg.Add(2)
	go handleWrite(conn, &wg)
	go handleRead(conn, &wg)
	wg.Wait()
	return true

	// 	if (this.socket_0.Connected)//如果套接字处于打开状态、则关闭
	// 	{
	// 		this.socket_0.Close();
	// 	}
	// 	this.socket_0 = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
	// 	IAsyncResult asyncResult = this.socket_0.BeginConnect(this.IPSetAdd, this.TCPPort, null, null);
	// 	DateTime now = DateTime.Now;
	// 	while (!asyncResult.IsCompleted)//超时检测
	// 	{
	// 		DateTime now2 = DateTime.Now;
	// 		if ((now2 - now).TotalMilliseconds > 3000.0)
	// 		{
	// 			return false;
	// 		}
	// 		Thread.Sleep(50);//每间隔50ms检测一次
	// 	}
	// 	result = true;
	// 	this.socket_0.EndConnect(asyncResult);//终止连接
	// 	this.socket_0.ReceiveTimeout = 3000;//3000ms无数据接收则超时
	// 	return result;
	// }
	// return result2;
}

func handleWrite(conn net.Conn, wg *sync.WaitGroup) {
	defer wg.Done()

	// for i := 10; i > 0; i-- {
	// 	d := "hello" + strconv.Itoa(i)
	// 	msg := Msg{
	// 		Data: d,
	// 		Type: 1,
	// 	}
	// 	b, _ := json.Marshal(msg)
	// 	writer := bufio.NewWriter(conn)
	// 	writer.Write(b)
	// 	writer.Write([]byte("\n"))
	// 	writer.Flush()
	// }
	fmt.Println("write done")
}

func handleRead(conn net.Conn, wg *sync.WaitGroup) {
	defer wg.Done()
	// reader := bufio.NewReader(conn)
	// for i := 1; i <= 10; i++ {
	// 	line, _, err := reader.ReadLine()
	// 	if err != nil {
	// 		fmt.Println("read error", err)
	// 		return
	// 	}
	// 	var resp Resp
	// 	json.Unmarshal(line, &resp)
	// 	fmt.Println("status", resp.Status, " content:", resp.Data)
	// }
	fmt.Println("read done")
}

// StartConnect 开始连接
func (d Device) StartConnect() {
	// bool result;
	// 	if (result = this.PLCconnect())//PLC连接状态返回值=0 连接失败
	//     {
	// 		this.PLCStatue = 2; /*TCP连接成功*/
	//         this.StopFlag = false;
	// 		this.thread = new Thread(new ParameterizedThreadStart(this.GetStatue));
	// 		this.thread.IsBackground = true;
	// 		this.thread.Start(this);
	// 	}
	// 	else
	// 	{
	// 		this.PLCStatue = 0; /*未连接*/
	//     }
	// 	return result;
}

// StopConnect 停止设备的连接
func (d Device) StopConnect() {
	// this.StopFlag = true;
	// 	if (this.thread != null && this.thread.IsAlive)
	// 	{
	// 		this.thread.Join(1000);
	// 	}
	// 	this.method_8();
}

// WriteData 向设备写入数据
func (d Device) WriteData(name string, value float64) {
	// name = name.Trim().ToUpper();
	// string[] array = name.Split(new char[]{'.'});//以.分隔数组
	// string key = array[0];
	// string key2 = array[1];
	// TagGroup tagGroup = this.device.TagGroups[key];
	// Tag tag = tagGroup.Tags[key2];
	// e_PLC_MMType e_PLC_MMType_ = tagGroup.Get_MMtype();
	// e_PLC_DATA_TYPE e_PLC_DATA_TYPE_ = tag.CheckDataType();
	// if (this.BackTrue(e_PLC_MMType_, e_PLC_DATA_TYPE_))
	// {
	// 	new WriteData(tagGroup, tag, value);
	// 	this.device.AddWriteData(tagGroup, tag, value);
	// }
}

// GetValue 传入一个以逗号分隔的key，这个key包括groupname和tagname
func (d Device) GetValue(key string) string {

	tempStr := strings.ToUpper(strings.TrimSpace(key))
	array := strings.Split(tempStr, ".")
	text := array[0]
	tagKey := array[1]
	tagGroup := d.TagGroup[text]
	tag := tagGroup.TagMap[tagKey]
	result, _ := tagGroup.GetValue(tag.Address)
	return result
	// object result;
	// switch (tag.CheckDataType())
	// {
	// case e_PLC_DATA_TYPE.TYPE_INT:
	// 	result = this.method_13(text, Convert.ToInt32(tag.Address));
	// 	break;
	// case e_PLC_DATA_TYPE.TYPE_FLOAT:
	// 	result = this.method_14(text, Convert.ToInt32(tag.Address));
	// 	break;
	// case e_PLC_DATA_TYPE.TYPE_BOOL:
	// {
	// 	string[] array2 = tag.Address.Split(new char[]
	// 	{
	// 		'.'
	// 	});
	// 	int int_ = Convert.ToInt32(array2[0]);
	// 	int int_2 = Convert.ToInt32(array2[1]);
	// 	result = this.method_16(text, int_, int_2);
	// 	break;
	// }
	// case e_PLC_DATA_TYPE.TYPE_SHORT:
	// 	result = this.method_15(text, Convert.ToInt32(tag.Address));
	// 	break;
	// case e_PLC_DATA_TYPE.TYPE_BYTE:
	// 	result = this.method_12(text, Convert.ToInt32(tag.Address));
	// 	break;
	// default:
	// 	result = -9999f;
	// 	break;
	// }
	// return result;
}

// GetStatue 获取状态
func (d Device) GetStatue() {
	// bool flag = false;
	// 	while (!this.StopFlag)
	// 	{
	//         #region  while
	//         if (!flag)
	// 		{
	// 			if (!this.device.ConnectToPLC(this.socket_0))
	// 			{
	// 				flag = false;
	// 				this.PLCStatue = 5; /*PLC握手错误*/
	//                 continue;
	// 			}
	// 			flag = true;
	// 			this.PLCStatue = 3; /*PLC握手成功*/
	//         }
	// 		if (this.device.ProcessPLCData(this.socket_0, this.StopFlag))
	// 		{
	// 			this.PLCStatue = 4; /*正常采集过程中..*/
	//         }
	// 		else
	// 		{
	// 			this.PLCStatue = 6; /*通讯错误*/
	//             while (!this.StopFlag)
	// 			{
	// 				if (this.PLCconnect())
	// 				{
	// 					flag = false;
	// 					break;
	// 				}
	// 				Thread.Sleep(1000);
	// 			}
	// 		}
	// 		Thread.Sleep(this.idelTime);
	//         #endregion
	//     }
	//     this.PLCStatue = 0; /*未连接*/
}
